package net.lzzy.practicesapi1.web.courses;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import net.lzzy.practicesapi1.constants.ApiConstant;
import net.lzzy.practicesapi1.constants.Messages;
import net.lzzy.practicesapi1.entities.Course;
import net.lzzy.practicesapi1.entities.User;
import net.lzzy.practicesapi1.services.CourseService;
import net.lzzy.practicesapi1.services.UserService;
import net.lzzy.practicesapi1.utils.StringUtil;
import net.lzzy.practicesapi1.web.models.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


/**
 * @author locker
 */
@Api(tags = "课程相关业务")
@CrossOrigin
@RestController
@RequestMapping(ApiConstant.ROUTE_COURSE_ROOT)
public class CourseApiController {
    private final CourseService service;
    private final UserService uService;

    @Autowired
    public CourseApiController(CourseService service, UserService uService) {
        this.service = service;
        this.uService = uService;
    }

    @ApiOperation("查看所有开放课程")
    @GetMapping(ApiConstant.ROUTE_COURSE_ALL)
    public ApiResult getCourses(@RequestParam String token) {
        List<VmCourse> courses = new ArrayList<>();
        service.get().forEach(course -> courses.add(VmCourse.create(course, false)));
        return new ApiResult(true, courses.size() + "", courses);
    }
    @ApiOperation("分页查询所有开放课程")
    @GetMapping(ApiConstant.ROUTE_COURSE_PAGE)
    public ApiResult getPagedCourses(@RequestParam String token, @RequestParam int page, @RequestParam int size) {
        List<VmCourse> courses = new ArrayList<>();
        service.get(page, size).forEach(course -> courses.add(VmCourse.create(course, false)));
        return new ApiResult(true, service.count() + "", courses);
    }
    @ApiOperation("")
    @GetMapping(ApiConstant.ROUTE_COURSE_OPEN)
    public ApiResult getOpenCourses(@RequestParam String token) {
        List<VmCourse> courses = new ArrayList<>();
        service.get(true).forEach(course -> courses.add(VmCourse.create(course, false)));
        return new ApiResult(true, courses.size() + "", courses);
    }

    @GetMapping(ApiConstant.ROUTE_COURSE_OPEN_PAGE)
    public ApiResult getPagedOpenCourses(@RequestParam String token, @RequestParam int page, @RequestParam int size) {
        List<VmCourse> courses = new ArrayList<>();
        service.get(page, size, true).forEach(course -> courses.add(VmCourse.create(course, false)));
        return new ApiResult(true, service.count(true) + "", courses);
    }

    @GetMapping(ApiConstant.ROUTE_COURSE_TEACHER)
    public ApiResult getTeachersCourses(@RequestParam String token, @RequestParam(name = "id") UUID teacherId) {
        List<VmCourse> courses = new ArrayList<>();
        service.getTeachersCourses(teacherId).forEach(course -> courses.add(VmCourse.create(course, true)));
        return new ApiResult(true, courses.size() + "", courses);
    }

    @GetMapping(ApiConstant.ROUTE_COURSE_STUDENT)
    public ApiResult getStudentsCourses(@RequestParam String token, @RequestParam(name = "id") UUID studentId) {
        List<VmCourse> courses = new ArrayList<>();
        service.getStudentsCourses(studentId).forEach(course -> courses.add(VmCourse.create(course, false)));
        return new ApiResult(true, courses.size() + "", courses);
    }

    private ApiResult addOrUpdate(UUID id, CourseInfo info) {
        String token = info.getToken();
        String name = info.getName();
        String desc = info.getDesc();
        String cover = info.getCover();
        boolean open = info.isOpen();
        String teacherId = info.getTeacher_id();
        if (StringUtil.isEmpty(name) ||
                StringUtil.isEmpty(desc) ||
                StringUtil.isEmpty(cover) ||
                StringUtil.isEmpty(teacherId)) {
            return new ApiResult(false, Messages.MISS_ARGS.toString(), null);
        }
        User teacher = uService.getUser(UUID.fromString(teacherId));
        if (teacher == null) {
            return new ApiResult(false, Messages.WRONG_ID.toString(), null);
        }
        Course course;
        boolean create = id == null;
        if (create) {
            course = new Course();
            course.setTeacher(teacher);
        } else {
            course = service.getById(id);
            if (course == null) {
                return new ApiResult(false, Messages.WRONG_ID.toString(), null);
            }
        }
        course.setName(name);
        course.setCover(cover);
        course.setDescription(desc);
        course.setOpen(open);
        if (create) {
            return new ApiResult(true, Messages.SUCCESS.toString(), VmCourse.create(service.add(course), true));
        } else {
            Course updated = service.update(course, token);
            if (updated == null) {
                return new ApiResult(false, Messages.NO_PERMISSION.toString(), null);
            }
            return new ApiResult(true, Messages.SUCCESS.toString(), VmCourse.create(updated, true));
        }
    }
    @ApiOperation("添加新课程")
    @ApiImplicitParam(
            name = "id",
            value = "课程id",
            required = true,
            dataType = "UUID",
            dataTypeClass = UUID.class,
            paramType = "path"
    )
    @PostMapping(ApiConstant.ROUTE_COURSE_ADD)
    public ApiResult add(@RequestBody CourseInfo info) {
        return addOrUpdate(null, info);
    }

    @PutMapping(ApiConstant.ROUTE_COURSE_PUT)
    public ApiResult update(@PathVariable UUID id, @RequestBody CourseInfo info) {
        return addOrUpdate(id, info);
    }

    @PostMapping(ApiConstant.ROUTE_COURSE_OPEN_CLOSE)
    public ApiResult openClose(@RequestBody CourseOpenInfo info) {
        String token = info.getToken();
        String strCourseId = info.getCourse_id();
        boolean open = info.isOpen();
        if (StringUtil.isEmpty(token) || StringUtil.isEmpty(strCourseId)) {
            return new ApiResult(false, Messages.MISS_ARGS.toString(), null);
        }
        Course course = service.openCloseCourse(UUID.fromString(strCourseId), open, token);
        if (course == null) {
            return new ApiResult(false, Messages.NO_PERMISSION.toString(), null);
        }
        return new ApiResult(true, Messages.SUCCESS.toString(), VmCourse.create(course, true));
    }

    @DeleteMapping(ApiConstant.ROUTE_COURSE_DELETE)
    public ApiResult delete(@RequestBody CourseKeyInfo info) {
        String token = info.getToken();
        String strCourseId = info.getCourse_id();
        if (StringUtil.isEmpty(token) || StringUtil.isEmpty(strCourseId)) {
            return new ApiResult(false, Messages.MISS_ARGS.toString(), null);
        }
        try {
            UUID courseId = UUID.fromString(strCourseId);
            Messages msg = service.remove(courseId, token);
            return new ApiResult(msg == Messages.SUCCESS, msg.toString(), null);
        } catch (Exception e) {
            return new ApiResult(false, Messages.WRONG_ID.toString(), null);
        }
    }
}
